﻿using Microsoft.AspNetCore.Components.Forms;

namespace Xms.Abp.Components;

public partial class DetailsViewContent<TService, TModel, TKey> : AntDomComponentBase
    where TService : class, ICrudService<TKey>
    where TModel : class, new()
    where TKey : struct
{
    public TModel Model { get; set; } = new TModel();

    [Inject] public TService AppService { get; set; }

    [Parameter] public RenderFragment<TModel> ChildContent { get; set; }

    [Parameter] public EventCallback<EditContext> OnFinish { get; set; }

    [Parameter] public Action<TModel, object> OnBeforeCreate { get; set; }

    [Parameter] public Action<TModel, object> OnBeforeUpdate { get; set; }

    [Parameter] public EventCallback<EditContext> OnFinishFailed { get; set; }

    [Parameter] public DialogAction DialogAction { get; set; }

    [Parameter] public TKey ModelId { get; set; }

    [Parameter] public object Obj { get; set; }

    [Parameter] public DetailsViewBase<TKey> Dialog { get; set; }

    [Parameter] public string DefaultTabTitle { get; set; }

    [Parameter] public RenderFragment<TModel> TabPanes { get; set; }

    protected bool Submiting { get; set; }

    bool isLoadModel = false;
    protected override async Task OnInitializedAsync()
    {
        if (DialogAction != DialogAction.Create)
        {
            if (!isLoadModel)
            {
                isLoadModel = true;
                Submiting = true;
                Model = await (AppService as ICrudDetailsService<TModel, TKey>).GetDetailsAsync(ModelId);
                Submiting = false;
            }
        }
        await base.OnInitializedAsync();
    }

    protected virtual async Task OnFinishAsync(EditContext editContext)
    {
        if (OnFinish.HasDelegate)
        {
            Submiting = true;
            if (DialogAction == DialogAction.Create)
            {
                OnBeforeCreate?.Invoke(Model, Obj);
            }
            else
            {
                OnBeforeUpdate?.Invoke(Model, Obj);
            }
            await OnFinish.InvokeAsync(editContext);
            Submiting = false;
            return;
        }
        if (DialogAction == DialogAction.Create)
        {
            Submiting = true;
            OnBeforeCreate?.Invoke(Model, Obj);
            if (await (AppService as ICrudCreateService<TModel>).CreateAsync(Model))
            {
                Submiting = false;
                await CloseFeedbackAsync(true);
            }
            else
            {
                Submiting = false;
            }
        }
        else
        {
            Submiting = true;
            OnBeforeUpdate?.Invoke(Model, Obj);
            if (await (AppService as ICrudUpdateService<TModel, TKey>).UpdateAsync(ModelId, Model))
            {
                Submiting = false;
                await CloseFeedbackAsync(true);
            }
            else
            {
                Submiting = false;
            }
        }
    }

    protected virtual async Task OnFinishFailedAsync(EditContext editContext)
    {
        if (OnFinishFailed.HasDelegate)
        {
            await OnFinishFailed.InvokeAsync(editContext);
            return;
        }
        await Task.CompletedTask;
    }

    protected async Task CloseFeedbackAsync(bool isSure)
    {
        if (Dialog.FeedbackRef is DrawerRef<bool> drawerRef)
        {
            await drawerRef!.CloseAsync(isSure);
        }
        else if (Dialog.FeedbackRef is ModalRef<bool> modalRef)
        {
            (isSure ? modalRef.OnOk : modalRef.OnCancel)?.Invoke(isSure);
            await modalRef!.CloseAsync();
        }
    }

    protected async Task CloseFeedbackAsync()
    {
        await CloseFeedbackAsync(false);
    }

    protected async Task ApprovedAsync()
    {
        var parameter = new ReviewParameter
        {
            IsApproved = true,
            ReviewRemark = (Model as IHasReviewRemark)?.ReviewRemark,
        };
        Submiting = true;
        if (await (AppService as ICrudReviewService<TModel, TKey>).ReviewAsync(ModelId, parameter))
        {
            Submiting = false;
            await CloseFeedbackAsync(true);
        }
        else
        {
            Submiting = false;
        }
    }

    protected async Task RejectAsync()
    {
        var parameter = new ReviewParameter
        {
            IsApproved = false,
            ReviewRemark = (Model as IHasReviewRemark)?.ReviewRemark,
        };
        Submiting = true;
        if (await (AppService as ICrudReviewService<TModel, TKey>).ReviewAsync(ModelId, parameter))
        {
            Submiting = false;
            await CloseFeedbackAsync(true);
        }
        else
        {
            Submiting = false;
        }
    }
}
